package com.wdb007.venus.svc.biz.manager;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.wdb007.venus.svc.biz.utils.DateFormatUtil;
import com.wdb007.venus.svc.biz.utils.HttpClientUtil;

/**
 * 微信支付相关接口
 * 
 * @author 张俊伟
 *
 */
@Component
public class WeChatPayClientManager {
	private Logger logger = LoggerFactory.getLogger(WeChatPayClientManager.class);
	private static HSSFWorkbook workbook = new HSSFWorkbook();
	
	@Autowired
	private ConfigInfoManager configInfoManager;
	
	@Autowired
	private WeChatUtilManager weChatUtilManager;
	
	public static void main(String[] args) {
	}
	
	/**
	 * 
	 * @Method:unifiedOrder
	 * @Description:微信统一下单接口
	 * @Time 2017年8月31日 上午11:46:10
	 * @author: Tom
	 * @param outTradeNo	商户系统内部订单号
	 * @param total_fee		交易总金额，单位为分
	 * @param spBillIp		客户真实IP
	 * @return
	 */
	public Map<String, String> unifiedOrder(String outTradeNo, String total_fee, String spBillIp) {
		WXPay pay = new WXPay(weChatUtilManager.getWxPayConfig());
		Map<String, String> params = weChatUtilManager.getTreeMapUnifiedOrder();
		// 向TreeMap中添加必填客户相关数据
		params.put("total_fee", total_fee);
		params.put("spbill_create_ip", spBillIp);
		params.put("out_trade_no", outTradeNo);
		try {
			logger.info("微信统一下单unifiedOrder请求参数Manager:{}", JSON.toJSONString(params));
			Map<String, String> result = pay.unifiedOrder(params);
			logger.info("微信统一下单unifiedOrder响应参数Manager:{}", JSON.toJSONString(result));
			return result;
		} catch (Exception e) {
			logger.error("请求微信统一下单失败"+e);
		}
		return null;
	}
	/**
	 * 
	 * @Method:queryOrderStatus
	 * @Description:主动查询订单
	 * @Time 2017年8月31日 下午1:51:03
	 * @author: Tom
	 * @param outTradeNo	商户系统内部订单号
	 * @return
	 */
	public Map<String,String> queryOrderStatus(String outTradeNo){
		WXPay pay = new WXPay(weChatUtilManager.getWxPayConfig());
		Map<String, String> params = weChatUtilManager.getTreeMapQueryOrder();
		params.put("out_trade_no", outTradeNo);
		try {
			return pay.orderQuery(params);
		} catch (Exception e) {
			logger.error("主动查询订单出错："+e);
		}
		return null;
	}
	/**
	 * 
	 * @Method:refundOrder
	 * @Description:申请退款
	 * @Time 2017年8月31日 下午2:06:18
	 * @author: Tom
	 * @param outTradeNo
	 * @param refundAmount
	 * @param total_amount 
	 * @return
	 */
	public Map<String,String> refundOrder(String outTradeNo, String refundAmount, String refundTradeNo, String total_amount){
		WXPay pay = new WXPay(weChatUtilManager.getWxPayConfig());
		Map<String,String> map = new HashMap<String,String>();
		Map<String, String> params = weChatUtilManager.getTreeMapRefundOrder();
		params.put("out_trade_no", outTradeNo);
		params.put("out_refund_no", refundTradeNo);
		params.put("total_fee", total_amount);
		params.put("refund_fee", refundAmount);
		try {
			map=pay.refund(params);
			logger.info("微信退押金返回数据\t"+map.toString());
			return map;
		} catch (Exception e) {
			logger.error("微信支付申请退款失败"+e);
		}
		return null;
	}
	/**
	 * 
	 * @Method:downloadBillW
	 * @Description:使用微信SDK进行请求数据，返回的数据在Map中直接为一个字符串，不利于将数据写入到xml
	 * @Time 2017年8月31日 下午3:10:15
	 * @author: Tom
	 * @param billDate
	 * @param billType
	 * @return
	 */
	public Map<String,String> downloadBillWeChatSdk(String billDate,String billType){
		WXPay pay = new WXPay(weChatUtilManager.getWxPayConfig());
		Map<String, String> params = weChatUtilManager.getTreeMapDodownloadBill();
		params.put("bill_date", billDate);
		params.put("bill_type", billType);
		try {
			return pay.downloadBill(params);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 
	 * @Method:downloadBill
	 * @Description:微信对账单,因为要将数据写入到xml中，故依旧使用此方式，使用流读取的方式
	 * @Time 2017年8月30日 下午5:29:20
	 * @author: Tom
	 * @param billDate
	 * @param billType
	 */
	public String downloadBill(String billDate,String billType, String filePath) {
		
		HSSFSheet sheet = workbook.createSheet("微信对账单"+DateFormatUtil.formatDate(new Date()));
		try {
			String uri = HttpClientUtil.getUri("https://api.mch.weixin.qq.com/pay/downloadbill", null);
			TreeMap<String, String> params = weChatUtilManager.getTreeMapDodownloadBill();
			params.put("bill_date", billDate);
			params.put("bill_type", billType);
			String keyWeChat = configInfoManager.getValue("wechat.key");
			String newXmlData = WXPayUtil.generateSignedXml(params, keyWeChat);
			System.out.println(newXmlData);
			//微信对账单返回的返回信息
			HttpPost post = new HttpPost(uri);
			post.setHeader("Content-Type", "text/xml;charset=utf-8");
			post.setEntity(new StringEntity(newXmlData,Charset.forName("UTF-8")));
			CloseableHttpClient httpClient = HttpClients.createDefault();
			CloseableHttpResponse response = httpClient.execute(post);
			HttpEntity entity = response.getEntity();
			String xmlData = null;
			StringBuffer bufferContent = new StringBuffer();
			int count = 0;
			if (entity != null) {
				System.out.println("Response content length: " + entity.getContentLength());
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
				System.out.println(bufferedReader);
				while ((xmlData = bufferedReader.readLine()) != null) {
					if(xmlData.startsWith("xml")) {
						//解析返回的xml
						bufferContent.append(xmlData);
					}
					this.padValue(sheet, xmlData,count);
					count++;
				}
				bufferedReader.close();
				//将文件保存到指定的位置
				FileOutputStream fos = null;
		        try {
		            fos = new FileOutputStream(filePath);
		            workbook.write(fos);
		            logger.info("微信对账单写入本地成功");
		        } catch (IOException e) {
		        	logger.error("将对账单的数据写入到本地文件出错："+e);
		        } finally {
		        	params.clear();
		        	fos.close();
		        }
		        if(bufferContent!=null) {
		        	return bufferContent.toString();
		        }
			}
		} catch (Exception e) {
			logger.error("微信对账单接口调用失败："+e);
		}
		return "true";
	}
	private boolean padValue(HSSFSheet sheet,String fileData,int count) {
		HSSFRow row = sheet.createRow(count);
		String headFields[] = fileData.split(",");
		for(int i=0;i<headFields.length;i++) {
			Cell cell = row.createCell(i);
			cell.setCellValue(headFields[i].replace("`", ""));
		}
		return true;
	}
	/*public String refundOrder(String outTradeNo,String refundAmount) {
		try {
			String uri = HttpClientUtil.getUri("https://api.mch.weixin.qq.com/secapi/pay/refund", null);
			TreeMap<String, String> params = WeChatUtil.getTreeMapRefundOrder();
			//数据库中拿去最近一次的押金充值订单号,订单金额
			params.put("out_trade_no", outTradeNo);
			params.put("total_fee", WeChatUtil.getStringPrice(refundAmount));
			params.put("refund_fee", WeChatUtil.getStringPrice(refundAmount));
			String sign = WeChatUtil.getSign(params, keyWeChat);
			params.put("sign", sign);
			String newXmlData = WeChatUtil.xmlData(params, xmlRefundOrder);
			//主动获取到的订单返回信息
			String xmlResponseData = HttpClientUtil.getPostBodyDataXml(uri, newXmlData);
			logger.info("申请退款接口返回："+xmlResponseData);
			System.out.println("申请退款接口返回："+xmlResponseData);
			WXPay pay = new WXPay(null);
			pay.refund(reqData, connectTimeoutMs, readTimeoutMs)
			return xmlResponseData;
		} catch (URISyntaxException e) {
			logger.error("微信支付订单查询"+e);
		}
		return null; 
	}*/
}